import { Command } from "commander";
import { ILoggable, Log, DeviceShell } from "@meminsight/core";
import { IProcess } from "./IProcess";
import { Version } from "../Version";

/**
 * Ark GC Process
 */
export class ArkGCProc implements IProcess, ILoggable { 
    public readonly DOMAIN: string = 'meminsight';
    public readonly TAG: string = ArkGCProc.name;
    public static readonly CMD: string = 'ark-gc';
    public static readonly DESC: string = "ark force gc process.";
    public static readonly VER: string = Version.ARK_GC.toString();
    private static _instance: ArkGCProc;

    private constructor() {}

    /**
     * get instance
     * @returns instance
     */
    public static instance(): ArkGCProc {
        if (!ArkGCProc._instance) {
            ArkGCProc._instance = new ArkGCProc();
        }
        return ArkGCProc._instance;
    }

    public initialize(proc: Command, any: any) {
        proc.command(ArkGCProc.CMD)
            .description(ArkGCProc.DESC)
            .option("-d, --device <target device id>", "target device id")
            .option("-b, --bundle <bundle name>", "bundle name")
            .option<number>("-p, --pid <target process pid>", "target process pid", parseInt)
            .action(async (options) => {
                await ArkGCProc.instance().process(new Map<string, any>([
                    ["device", options.device],
                    ["bundle", options.bundle || undefined],
                    ["pid", options.pid || -1]
                ]));
            });
    }

    private async process(args: Map<string, any>): Promise<void> {
        let device = args.get("device");

        // 优先选择 pid 进行 GC
        let pid : number = args.get('pid');
        if (pid !== -1) {   
            return await DeviceShell.getDeviceShell(device).forceGC(pid); 
        } 

        let bundleName = args.get("bundle");
        if (bundleName) {
            return await DeviceShell.getDeviceShell(device).forceGCByName(bundleName);
        }
        
        Log.errorX(this, "Args: bundle name or pid is required");
    }
}